package com.iwhalecloud.bss.kite.cucc.service.scene.query;

import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneAccessProdInstService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.dto.inst.InstAttrDTO;
import com.iwhalecloud.bss.kite.client.dto.inst.ProdInstDTO;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.util.KiteObjectUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.common.validate.annotation.KiteNotBlank;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteProdInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.manager.inst.graph.impl.RelEdge;
import com.iwhalecloud.bss.kite.service.scene.AbstractInstService;
import com.iwhalecloud.bss.kite.service.scene.attr.OperateInstAttrService;
import com.iwhalecloud.bss.kite.service.scene.bo.QuerySceneAccessProdInstServiceBO;
import com.iwhalecloud.bss.kite.service.util.CopyToDtoUtil;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service("querySceneAccessProdInstService")
public class QuerySceneAccessProdInstService extends AbstractInstService implements IQuerySceneAccessProdInstService {

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    private OperateInstAttrService operateInstAttrService;

    @Autowired
    private QuerySceneAccessProdInstServiceBO querySceneAccessProdInstServiceBO;

    /***
     * 通过实例id定位某个具体的产品实例对象；
     *
     * @param sceneInstId
     * @param prodInstId
     * @param custId 客户id，分片字段，必填
     * @return
     */
    @Override
    @Validated
    public DataResult<ProdInstDTO> getSceneProdInstByProdInstId(@KiteNotBlank String sceneInstId,
        @KiteNotBlank String prodInstId, @KiteNotBlank String custId) {
        KiteProdInst kiteProdInst = querySceneInstService.getProdInst(custId, prodInstId);
        ProdInstDTO dto = null;
        if (!KiteObjectUtils.isEmpty(kiteProdInst)) {
            dto = CopyToDtoUtil.packageProdInstDTOForAccess(kiteProdInst, kiteProdInst.getOfferInstId());
            // TODO 待确认 装箱
        }
        // else {
        // dto = queryAccessProdInstBO.getAccessProdInstByProdInstId(prodInstId, custId);
        // checkAndPutProdInst(dto, queryAccessProdInstBO);
        // }
        return ErrorConsts.SUCCESS.getResult(dto);
    }

    /***
     * 获取所有接入产品实例
     *
     * @param sceneInstId
     * @param custId 客户id，分片字段，必填
     * @return
     */
    @Override
    public DataResult<List<ProdInstDTO>> listProdInsts(String sceneInstId, String custId) {
        List<KiteProdInst> kiteProdInstList = querySceneAccessProdInstServiceBO.listProdInsts(sceneInstId, custId);
        List<ProdInstDTO> dtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(kiteProdInstList)) {
            //TODO 性能分析 电信的从数据库加载实例的时候才有用
            KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
            kiteProdInstList.forEach(prodInst -> {
                operateInstAttrService.getKiteInstAttrs(prodInst, prodInst.listAttrs(), sceneInst);
            });
            kiteProdInstList.removeIf(prodInst -> Objects.equals(Boolean.TRUE, prodInst.getIsHide()));
            dtoList = CopyToDtoUtil.transProdInstDtoListForAccess(kiteProdInstList);
        }
        return ErrorConsts.SUCCESS.getResult(dtoList);
    }

    /***
     * 获取有效接入产品实例
     *
     * @param sceneInstId
     * @param custId 客户id，分片字段，必填
     * @return
     */
    @Override
    public DataResult<List<ProdInstDTO>> listEffProdInsts(String sceneInstId, String custId) {
        List<ProdInstDTO> prodInstList = listProdInsts(sceneInstId, custId).getResultObject();
        prodInstList.removeIf(prodInst -> Objects.equals(prodInst.getActionType(), ActionType.D.name()));
        return ErrorConsts.SUCCESS.getResult(prodInstList);
    }

    /***
     * 获取带规格信息的产品实例属性
     *
     * @param sceneInstId
     * @param prodInstId
     * @param custId 客户id，分片字段，必填
     * @return
     */
    @Override
    public DataResult<List<InstAttrDTO>> listSceneProdInstAttrByProdInstId(String sceneInstId, String prodInstId,
        String custId) {
        List<KiteAttr> kiteAttrList = querySceneInstService.listProdInstAttrs(custId, prodInstId);
        kiteAttrList = operateInstAttrService.sortProdAttr(kiteAttrList);
        List<InstAttrDTO> dtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(kiteAttrList)) {
            dtoList = CopyToDtoUtil.transInstAttrDtoList(kiteAttrList);
        }
        // else {
        // dtoList = queryAccessProdInstBO.listProdInstAttrs(prodInstId, custId);
        // checkAndPutAttr(dtoList, sceneInstId, prodInstId);
        // }
        return ErrorConsts.SUCCESS.getResult(dtoList);
    }

    /**
     * Description: <br>
     * 获取接入产品实例属性
     *
     * @param sceneInstId
     * @param custId
     * @param prodInstId
     * @param showType
     * @return <br>
     */
    @Override
    public DataResult<List<InstAttrDTO>> getPordInstAttrs(String sceneInstId, String custId, String prodInstId,
        String showType) {
        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
        KiteProdInst inst = querySceneInstService.getProdInst(custId, prodInstId);
        List<KiteAttr> kiteAttrList = inst.listAttrs();

        kiteAttrList = kiteAttrList.stream().filter(
            kiteAttr -> KiteStringUtils.equals(showType, kiteAttr.getShowType()) || KiteStringUtils.isEmpty(showType))
            .collect(Collectors.toList());
        operateInstAttrService.getKiteInstAttrs(inst, kiteAttrList, sceneInst);
        kiteAttrList = operateInstAttrService.sortProdAttr(kiteAttrList);
        List<InstAttrDTO> dtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(kiteAttrList)) {
            dtoList = CopyToDtoUtil.transInstAttrDtoList(kiteAttrList);
        }

        return ErrorConsts.SUCCESS.getResult(dtoList);
    }

    /***
     * 获取终端资源使用接入产品实例
     * @param sceneInstId
     * @param offerResInstRelId
     * @return
     */
    @Override
    public DataResult<ProdInstDTO> getProdInstByOfferResInstRelId(String sceneInstId, String offerResInstRelId) {

        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
        KiteProdInst kiteProdInst = querySceneInstService
            .getProdInstByOfferResInstRelId(sceneInst.getCustId(), offerResInstRelId);
        ProdInstDTO dto = null;
        if (!KiteObjectUtils.isEmpty(kiteProdInst)) {
            dto = CopyToDtoUtil.packageProdInstDTOForAccess(kiteProdInst, kiteProdInst.getOfferInstId());
        }
        return ErrorConsts.SUCCESS.getResult(dto);
    }

    /**
     * 判断接入产品实例是否有有效的套餐销售品实例
     *
     * @param custId 客户id
     * @param prodInstId 接入产品实例id
     * @return
     */
    @Override
    public DataResult<Boolean> isProdInstHasMainOfferInst(String custId, String prodInstId) {
        return ErrorConsts.SUCCESS.getResult(querySceneInstService.isProdInstHasMainOfferInst(custId, prodInstId));
    }

    @Override
    public KiteProdInst getProdInst(String custId, String prodInstId) {
        return querySceneInstService.getProdInst(custId, prodInstId);
    }

    @Override
    public DataResult<List<Map<String, String>>> getTransferenceProducts(String prodInstId) {
        return ErrorConsts.SUCCESS.getResult(querySceneAccessProdInstServiceBO.getTransferenceProducts(prodInstId));
    }

    /**
     * Description: <br>
     *
     * @param custId
     * @param prodInstId
     * @return <br>
     */
    @Override
    public DataResult<List<RelEdge>> listParentInstRels(String custId, String instId, InstType instType) {
        List<RelEdge> parentInstRels = querySceneInstService.listParentInstRels(custId, instType, instId);
        return ErrorConsts.SUCCESS.getResult(parentInstRels);
    }

    /**
     * Description: <br>
     *
     * @param custId
     * @param instId
     * @param instType
     * @return <br>
     */
    @Override
    public DataResult<List<RelEdge>> listSubInstRels(String custId, String instId, InstType instType) {
        List<RelEdge> subInstRels = querySceneInstService.listSubInstRels(custId, instType, instId);
        return ErrorConsts.SUCCESS.getResult(subInstRels);
    }
}
